home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / Draw / Sources / DrawSel.cpp < prev    next >
Encoding:
Text File  |  1996-04-25  |  26.1 KB  |  943 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                DrawSel.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Author:                Henri Lamiraux
  7. //
  8. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "ODFDraw.hpp"
  13.  
  14. #ifndef DRAWSEL_H
  15. #include "DrawSel.h"
  16. #endif
  17.  
  18. #ifndef DRAWCONT_H
  19. #include "DrawCont.h"
  20. #endif
  21.  
  22. #ifndef DRAWFRM_H
  23. #include "DrawFrm.h"
  24. #endif
  25.  
  26. #ifndef DRAWPART_H
  27. #include "DrawPart.h"
  28. #endif
  29.  
  30. #ifndef BASESHP_H
  31. #include "BaseShp.h"
  32. #endif
  33.  
  34. #ifndef BOUNDSHP_H
  35. #include "BoundShp.h"
  36. #endif
  37.  
  38. #ifndef LINESHP_H
  39. #include "LineShp.h"
  40. #endif
  41.  
  42. #ifndef OVALSHP_H
  43. #include "OvalShp.h"
  44. #endif
  45.  
  46. #ifndef RECTSHP_H
  47. #include "RectShp.h"
  48. #endif
  49.  
  50. #ifndef RRECTSHP_H
  51. #include "RRectShp.h"
  52. #endif
  53.  
  54. #ifndef TEXTSHP_H
  55. #include "TextShp.h"
  56. #endif
  57.  
  58. #ifndef DRAWCLIP_H
  59. #include "DrawClip.h"
  60. #endif
  61.  
  62. #ifndef DRAWPRXY_H
  63. #include "DrawPrxy.h"
  64. #endif
  65.  
  66. #ifndef UTILS_H
  67. #include "Utils.h"
  68. #endif
  69.  
  70. #ifndef SHPTRAKR_H
  71. #include "ShpTrakr.h"
  72. #endif
  73.  
  74. #ifndef DRAWCMDS_H
  75. #include "DrawCmds.h"
  76. #endif
  77.  
  78. #ifndef DRAWLINK_H
  79. #include "DrawLink.h"
  80. #endif
  81.  
  82. #ifndef DRWPRMSE_H
  83. #include "DrwPrmse.h"
  84. #endif
  85.  
  86. // ----- Part Layer -----
  87.  
  88. #ifndef FWCONTXT_H
  89. #include "FWContxt.h"
  90. #endif
  91.  
  92. #ifndef FWITERS_H
  93. #include "FWIters.h"
  94. #endif
  95.  
  96. #ifndef FWUTIL_H
  97. #include "FWUtil.h"
  98. #endif
  99.  
  100. #ifndef FWPRESEN_H
  101. #include "FWPresen.h"
  102. #endif
  103.  
  104. // ----- OS Layer -----
  105.  
  106. #ifndef FWORDCOL_H
  107. #include "FWOrdCol.h"
  108. #endif
  109.  
  110. #ifndef FWSUSINK_H
  111. #include "FWSUSink.h"
  112. #endif
  113.  
  114. #ifndef FWODGEOM_H
  115. #include "FWODGeom.h"
  116. #endif
  117.  
  118. #ifndef FWEVENT_H
  119. #include "FWEvent.h"
  120. #endif
  121.  
  122. #ifndef SLMixOS_H
  123. #include "SLMixOS.h"
  124. #endif
  125.  
  126. // ----- Foundation Includes -----
  127.  
  128. #ifndef FWSTREAM_H
  129. #include "FWStream.h"
  130. #endif
  131.  
  132. // ----- OpenDoc Includes -----
  133.  
  134. #ifndef SOM_ODShape_xh
  135. #include <Shape.xh>
  136. #endif
  137.  
  138. #ifndef SOM_ODStorageUnit_xh
  139. #include <StorageU.xh>
  140. #endif
  141.  
  142. #ifndef SOM_Module_OpenDoc_StdProps_defined
  143. #include <StdProps.xh>
  144. #endif
  145.  
  146. #ifndef SOM_ODSession_xh
  147. #include <ODSessn.xh>
  148. #endif
  149.  
  150. #if defined(__MWERKS__) && GENERATING68K
  151. // A hack to work around a bug
  152. #pragma import list somGetGlobalEnvironment
  153. #endif
  154.  
  155. //========================================================================================
  156. //    Runtime Informations
  157. //========================================================================================
  158.  
  159. #ifdef FW_BUILD_MAC
  160. #pragma segment odfdraw2
  161. #endif
  162.  
  163. //========================================================================================
  164. //    class CDrawSelection
  165. //========================================================================================
  166.  
  167. FW_DEFINE_AUTO(CDrawSelection)
  168.     
  169. //----------------------------------------------------------------------------------------
  170. //    CDrawSelection::CDrawSelection
  171. //----------------------------------------------------------------------------------------
  172.  
  173. CDrawSelection::CDrawSelection(Environment* ev, CDrawPart* drawPart):
  174.     FW_CSelection(ev, TRUE, TRUE),
  175.     fDrawPart(drawPart),
  176.     fUpdateShape(NULL),
  177.     fFrozenCount(0),
  178.     fCount(0),
  179.     fSelectionContent(NULL),
  180.     fWorkingHandle(FW_kZeroRect, FW_kFill),
  181.     fDraggedContent(NULL)
  182. {
  183.     fSelectionContent = FW_NEW(CDrawSelectionContent, (ev, drawPart, this));
  184.     fWorkingHandle.SetInk(FW_kInvertInk);
  185.     FW_END_CONSTRUCTOR
  186. }
  187.  
  188. //----------------------------------------------------------------------------------------
  189. //    CDrawSelection::~CDrawSelection
  190. //----------------------------------------------------------------------------------------
  191.  
  192. CDrawSelection::~CDrawSelection()
  193. {
  194.     FW_START_DESTRUCTOR
  195.     if (fUpdateShape)
  196.         fUpdateShape->Release(somGetGlobalEnvironment());
  197. }
  198.  
  199. //----------------------------------------------------------------------------------------
  200. //    CDrawSelection::GetSelectedContent
  201. //----------------------------------------------------------------------------------------
  202.  
  203. FW_CContent* CDrawSelection::GetSelectedContent(Environment* ev)
  204. {
  205.     return fSelectionContent;
  206. }
  207.  
  208. //----------------------------------------------------------------------------------------
  209. //    CDrawSelection::WhichHandle
  210. //----------------------------------------------------------------------------------------
  211.  
  212. CBaseShape* CDrawSelection::WhichHandle(Environment* ev, FW_CGraphicContext& gc, const FW_CPoint& mouse, short& whichHandle) const
  213. {
  214.     whichHandle = 0;
  215.     
  216.     if (fCount != 0)
  217.     {
  218.         CDrawContentShapeIterator ite(fSelectionContent);
  219.         for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  220.         {
  221.             whichHandle = shape->WhichHandle(gc, mouse);
  222.             if (whichHandle != 0)
  223.                 return shape;
  224.         }
  225.     }
  226.     
  227.     return NULL;
  228. }
  229.  
  230. //----------------------------------------------------------------------------------------
  231. //    CDrawSelection::RenderSelectionHandles
  232. //----------------------------------------------------------------------------------------
  233.  
  234. void CDrawSelection::RenderSelectionHandles(Environment* ev, FW_CGraphicContext& gc)
  235. {
  236.     CDrawContentShapeIterator ite(fSelectionContent);
  237.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  238.     {
  239.         shape->RenderHandles(gc);    
  240.     }
  241. }
  242.  
  243. //----------------------------------------------------------------------------------------
  244. //    CDrawSelection::RenderAllHandles
  245. //----------------------------------------------------------------------------------------
  246.  
  247. void CDrawSelection::RenderAllHandles(Environment* ev, FW_CFrame* frame)
  248. {
  249.     if (fCount != 0)
  250.     {        
  251.         FW_CFrameFacetIterator ite(ev, frame);
  252.         for (ODFacet* facet = (ODFacet*)ite.First(ev); ite.IsNotComplete(ev); facet = (ODFacet*)ite.Next(ev))
  253.         {
  254.             FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
  255.             RenderSelectionHandles(ev, vc);
  256.         }
  257.     }
  258. }
  259.  
  260. //----------------------------------------------------------------------------------------
  261. //    CDrawSelection::RenderHandles
  262. //----------------------------------------------------------------------------------------
  263.  
  264. void CDrawSelection::RenderHandles(Environment* ev, CBaseShape* shape)
  265. {
  266.     FW_CPresentationFrameIterator ite(ev, GetPresentation(ev));
  267.     for (FW_CFrame* frame = ite.First(ev); ite.IsNotComplete(ev); frame = ite.Next(ev))
  268.     {
  269.         if (frame->HasSelectionFocus(ev) && frame->GetWindow(ev)->IsActive(ev))
  270.         {
  271.             FW_CFrameFacetIterator i(ev, frame);            
  272.             for (ODFacet* facet = i.First(ev); i.IsNotComplete(ev); facet = i.Next(ev))
  273.             {
  274.                 FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
  275.                 shape->RenderHandles(vc);
  276.             }
  277.         }
  278.     }
  279. }
  280.  
  281. //----------------------------------------------------------------------------------------
  282. //    CDrawSelection::CloseSelection
  283. //----------------------------------------------------------------------------------------
  284.  
  285. void CDrawSelection::CloseSelection(Environment* ev)
  286. {
  287.     CBaseShape* shape;
  288.     while ((shape = fSelectionContent->GetFirstShape()) != NULL)
  289.     {
  290.         DoRemove(ev, shape);
  291.         RenderHandles(ev, shape);        // turn off
  292.     }
  293.  
  294.     CalcCache(ev);
  295. }
  296.  
  297. //----------------------------------------------------------------------------------------
  298. //    CDrawSelection::AddToSelection
  299. //----------------------------------------------------------------------------------------
  300.  
  301. void CDrawSelection::AddToSelection(Environment* ev, CBaseShape* theShape, FW_Boolean renderHandles)
  302. {                
  303.     if (theShape != NULL)
  304.     {
  305.         fDrawPart->SetTool(ev, kSelectTool);
  306.         DoAdd(ev, theShape);
  307.         if (renderHandles)
  308.             RenderHandles(ev, theShape);    // Turn on    
  309.     }        
  310.             
  311.     CalcCache(ev);
  312. }
  313.  
  314. //----------------------------------------------------------------------------------------
  315. //    CDrawSelection::RemoveFromSelection
  316. //----------------------------------------------------------------------------------------
  317.  
  318. void CDrawSelection::RemoveFromSelection(Environment* ev, CBaseShape* shape, FW_Boolean renderHandles)
  319. {                
  320.     if (shape != NULL)
  321.     {
  322.         DoRemove(ev, shape);
  323.         if (renderHandles)
  324.             RenderHandles(ev, shape);        // Turn Off
  325.     }    
  326.     
  327.     CalcCache(ev);
  328. }
  329.  
  330. //----------------------------------------------------------------------------------------
  331. //    CDrawSelection::DoAdd
  332. //----------------------------------------------------------------------------------------
  333.  
  334. void CDrawSelection::DoAdd(Environment* ev, CBaseShape *shape)
  335. {
  336.     fSelectionContent->AddShape(ev, shape);
  337.     this->ShapeAdded(ev, shape);
  338. }
  339.  
  340. //----------------------------------------------------------------------------------------
  341. //    CDrawSelection::ShapeAdded
  342. //----------------------------------------------------------------------------------------
  343. void CDrawSelection::ShapeAdded(Environment* ev, CBaseShape* shape)
  344. {
  345.     shape->SelectShape(ev, true);
  346.     fCount++;
  347.     if (shape->IsFrozen())
  348.         fFrozenCount++;
  349. }
  350.  
  351. //----------------------------------------------------------------------------------------
  352. //    CDrawSelection::DoRemove
  353. //----------------------------------------------------------------------------------------
  354.  
  355. void CDrawSelection::DoRemove(Environment* ev, CBaseShape *shape)
  356. {
  357.     fSelectionContent->RemoveShape(ev, shape);
  358.     shape->SelectShape(ev, false);
  359.     fCount--;
  360.     if (shape->IsFrozen())
  361.         fFrozenCount--;
  362. }
  363.  
  364. //----------------------------------------------------------------------------------------
  365. //    CDrawSelection::ClearSelection
  366. //----------------------------------------------------------------------------------------
  367.  
  368. void CDrawSelection::ClearSelection(Environment* ev)
  369. {
  370.     CBaseShape *shape;
  371.     while ((shape = fSelectionContent->GetFirstShape()) != NULL)
  372.     {
  373.         shape->CheckPromise(ev, fDrawPart);
  374.         
  375.         DoRemove(ev, shape);                // Remove from selection list
  376.         fDrawPart->RemoveShapeFromPart(ev, shape);    // Remove from part
  377.     }
  378.     
  379.     CDrawFacetClipper facetClipper(ev, fDrawPart);
  380.     facetClipper.Clip(ev, GetPresentation(ev), fUpdateShape);
  381.     GetPresentation(ev)->Invalidate(ev, fUpdateShape);
  382.     
  383.     CalcCache(ev);
  384. }
  385.  
  386. //----------------------------------------------------------------------------------------
  387. //    CDrawSelection::SelectAll
  388. //----------------------------------------------------------------------------------------
  389.  
  390. void CDrawSelection::SelectAll(Environment* ev)
  391. {    
  392.     FW_CFrame* activeFrame = fDrawPart->GetLastActiveFrame(ev);
  393.     
  394.     RenderAllHandles(ev, activeFrame);
  395.  
  396.     CDrawContentShapeIterator ite(fDrawPart->GetDrawContent());
  397.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  398.     {
  399.         if (!shape->IsSelectedShape())
  400.             DoAdd(ev, shape);
  401.     }
  402.     
  403.     RenderAllHandles(ev, activeFrame);
  404.  
  405.     CalcCache(ev);
  406.     
  407.     fDrawPart->SetTool(ev, kSelectTool);
  408. }
  409.  
  410. //----------------------------------------------------------------------------------------
  411. //    CDrawSelection::IsEmpty
  412. //----------------------------------------------------------------------------------------
  413.  
  414. FW_Boolean CDrawSelection::IsEmpty(Environment* ev) const
  415. {    
  416.     return fCount == 0;
  417. }
  418.  
  419. //----------------------------------------------------------------------------------------
  420. //    CDrawSelection::CenterSelection
  421. //----------------------------------------------------------------------------------------
  422.  
  423. FW_CPoint CDrawSelection::CenterSelection(Environment* ev, FW_CFrame* scopeFrame)
  424. {
  425.     FW_ASSERT(scopeFrame);
  426.     
  427.     fDrawPart->SetTool(ev, kSelectTool);
  428.  
  429.     CalcCache(ev);
  430.     
  431.     FW_CRect bounds = scopeFrame->GetContentView(ev)->GetBoundsInContent(ev);
  432.     FW_CRect box(fDragRect);
  433.     box.PlaceInCenter(bounds);
  434.             
  435.     FW_CPoint result(box.left - fDragRect.left, box.top - fDragRect.top);
  436.     OffsetSelection(ev, result.x, result.y);
  437.     
  438.     CDrawFacetClipper facetClipper(ev, fDrawPart);
  439.     facetClipper.Clip(ev, GetPresentation(ev), fUpdateShape);    
  440.     GetPresentation(ev)->Invalidate(ev, fUpdateShape);
  441.  
  442.     return result;
  443. }
  444.  
  445. //----------------------------------------------------------------------------------------
  446. //    CDrawSelection::Resize
  447. //----------------------------------------------------------------------------------------
  448.  
  449. FW_Boolean CDrawSelection::Resize(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  450. {    
  451.     if (fClickedHandle == 0)
  452.         return FALSE;
  453.         
  454.     if (!this->IsOKtoEdit(ev))    // can't resize read only part
  455.     {
  456.         FW_Beep();
  457.         return TRUE;
  458.     }
  459.                 
  460.     if (!theMouseEvent.WaitUntilMouseMoved(ev))
  461.         return TRUE;
  462.     
  463.     ODFacet* facet = theMouseEvent.GetFacet(ev);
  464.     FW_CFrame *frame = FW_CFrame::ODtoFWFrame(ev, facet->GetFrame(ev));
  465.  
  466.     CBaseShape* anchorShape = GetAnchorShape();
  467.     
  468.     FW_CInk resizeInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
  469.     FW_CStyle resizeStyle(anchorShape->GetResizeStyle());
  470.     
  471.     CResizeTracker resizeTracker(ev, frame->GetContentView(ev), facet, anchorShape, fClickedHandle, resizeInk, resizeStyle, TRUE);
  472.     if (resizeTracker.Track(ev, theMouseEvent))
  473.     {
  474.         GetPresentation(ev)->Invalidate(ev, fUpdateShape);
  475.  
  476.         FW_CPoint lastLocation;
  477.         resizeTracker.GetLastLocation(lastLocation);
  478.         FW_CRect srcRect, dstRect;
  479.         anchorShape->GetMapRects(fClickedHandle, lastLocation, srcRect, dstRect);
  480.  
  481.         CResizeShapeCommand* cmd = FW_NEW(CResizeShapeCommand,
  482.                                             (ev, fDrawPart, frame, this,
  483.                                              srcRect, dstRect));
  484.         cmd->Execute(ev);
  485.     }
  486.     else
  487.     {
  488.         FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
  489.         
  490.         FW_CPoint penSize = vc.DeviceToLogical(2, 2);
  491.         anchorShape->CalcHandle(fClickedHandle, &fWorkingHandle, penSize);
  492.         fWorkingHandle.Render(vc);    // redraw the handle
  493.     }
  494.     
  495.     return TRUE;
  496. }
  497.  
  498. //----------------------------------------------------------------------------------------
  499. //    CDrawSelection::CalcCache
  500. //----------------------------------------------------------------------------------------
  501.  
  502. void CDrawSelection::CalcCache(Environment* ev)
  503. {
  504.     fDragRect.Clear();
  505.     
  506.     if (fUpdateShape == NULL)
  507.         fUpdateShape = ::FW_NewODShape(ev);
  508.     
  509.     if (fCount == 0)
  510.         return;
  511.     
  512.     FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
  513.     FW_CRect tempRect;
  514.  
  515.     FW_Boolean first = TRUE;
  516.     CDrawContentShapeIterator ite(fSelectionContent);
  517.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  518.     {
  519.         shape->GetDragRect(tempRect);
  520.         shape->GetUpdateBox(ev, aqTempShape);
  521.         if (first)
  522.         {
  523.             fDragRect = tempRect;
  524.             fUpdateShape->CopyFrom(ev, aqTempShape);
  525.         }
  526.         else
  527.         {
  528.             fDragRect |= tempRect;
  529.             fUpdateShape->Union(ev, aqTempShape);
  530.         }
  531.                         
  532.         first = FALSE;
  533.     }
  534.     
  535. }
  536.  
  537. //----------------------------------------------------------------------------------------
  538. //    CDrawSelection::CreateSelectionShape
  539. //----------------------------------------------------------------------------------------
  540.  
  541. ODShape* CDrawSelection::CreateSelectionShape(Environment* ev, ODFacet* facet, FW_CFrame* frame) const
  542. {
  543. FW_UNUSED(frame);
  544. FW_UNUSED(facet);
  545.  
  546.     ODShape* shape = ::FW_NewODShape(ev, fDragRect);
  547.     return shape;
  548. }
  549.  
  550. //----------------------------------------------------------------------------------------
  551. //    CDrawSelection::CreateSelectionShape
  552. //----------------------------------------------------------------------------------------
  553.  
  554. ODShape* CDrawSelection::CreateSelectionOutline(Environment* ev, ODFacet* facet, FW_CFrame* frame) const
  555. {
  556.     ODShape* outline;
  557.     if (GetAnchorShape() == NULL)
  558.         outline = CreateSelectionShape(ev, facet, frame);
  559.     else
  560.         outline = GetAnchorShape()->CreateShapeOutline(ev);
  561.  
  562.     if (fCount > 1)
  563.     {
  564.         FW_CAcquiredODShape shapeOutline = FW_CSelection::CreateSelectionOutline(ev, facet, frame);
  565.         outline->Union(ev, shapeOutline);
  566.     }
  567.  
  568.     return outline;
  569. }
  570.  
  571. //----------------------------------------------------------------------------------------
  572. //    CDrawSelection::OffsetSelection
  573. //----------------------------------------------------------------------------------------
  574.  
  575. void CDrawSelection::OffsetSelection(Environment* ev, FW_Fixed xDelta, FW_Fixed yDelta)
  576. {
  577.     FW_CAcquiredODShape aqUnionShape(fUpdateShape->Copy(ev));
  578.     
  579.     CDrawContentShapeIterator ite(fSelectionContent);
  580.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  581.     {
  582.         shape->OffsetShape(ev, xDelta, yDelta);
  583.     }
  584.     
  585.     CalcCache(ev);
  586.  
  587.     aqUnionShape->Union(ev, fUpdateShape);
  588.     
  589.     CDrawFacetClipper facetClipper(ev, fDrawPart);
  590.     facetClipper.Clip(ev, GetPresentation(ev), aqUnionShape);
  591. }
  592.  
  593. //----------------------------------------------------------------------------------------
  594. //    CDrawSelection::SelectWithRectangle
  595. //----------------------------------------------------------------------------------------
  596.  
  597. void CDrawSelection::SelectWithRectangle(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  598. {
  599.     CRectShape rectShape;    // Create a rect shape on the stack
  600.     FW_CStyle trackStyle(FW_kFixed0, FW_kAntPat);
  601.     FW_CInk trackInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
  602.     rectShape.ChangeRenderVerb(ev, fDrawPart, kFrameOnly);
  603.     rectShape.SetFrameInk(trackInk);
  604.     rectShape.SetFrameStyle(trackStyle);
  605.     
  606.     ODFacet* facet = theMouseEvent.GetFacet(ev);
  607.     FW_CFrame *frame = FW_CFrame::ODtoFWFrame(ev, facet->GetFrame(ev));
  608.  
  609.     CShapeTracker tracker(ev, frame->GetContentView(ev), facet, &rectShape, FALSE);
  610.     if (tracker.Track(ev, theMouseEvent))
  611.     {
  612.         FW_Boolean isShift = theMouseEvent.IsExtendModifier(ev);
  613.         FW_CRect selectRect = rectShape.GetRectGeometry();
  614.         
  615.         CDrawContentShapeIterator ite(fDrawPart->GetDrawContent());
  616.         for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  617.         {
  618.             if (shape->InSelectionRect(selectRect))
  619.             {
  620.                 if (shape->IsSelectedShape())
  621.                 {
  622.                     if (isShift)
  623.                     {
  624.                         DoRemove(ev, shape);
  625.                         RenderHandles(ev, shape);        // Turn Off
  626.                     }
  627.                 }
  628.                 else
  629.                 {
  630.                     DoAdd(ev, shape);
  631.                     RenderHandles(ev, shape);    // Turn on    
  632.                 }
  633.             }
  634.             else if (shape->IsSelectedShape() && !isShift)
  635.             {
  636.                 DoRemove(ev, shape);
  637.                 RenderHandles(ev, shape);        // Turn Off
  638.             }
  639.         }            
  640.         CalcCache(ev);
  641.     }
  642.     else
  643.     {
  644.         if (!theMouseEvent.IsExtendModifier(ev))
  645.             CloseSelection(ev);
  646.     }
  647. }
  648.  
  649. //----------------------------------------------------------------------------------------
  650. //    CDrawSelection::SetFrozen
  651. //----------------------------------------------------------------------------------------
  652.  
  653. void CDrawSelection::SetFrozen(Environment* ev, FW_Boolean state)
  654. {
  655.     CDrawContentShapeIterator ite(fSelectionContent);
  656.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  657.     {
  658.         if (shape->SetFrozen(state))
  659.         {
  660.             state ? fFrozenCount++ : fFrozenCount--;
  661.         }
  662.     }
  663. }
  664.  
  665. //----------------------------------------------------------------------------------------
  666. //    CDrawSelection::SelectionChanged
  667. //----------------------------------------------------------------------------------------
  668.  
  669. void CDrawSelection::SelectionChanged(Environment* ev)
  670. {
  671.     CDrawPublishLinkCollection temp;
  672.     
  673.     CDrawContentShapeIterator ite(fSelectionContent);
  674.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  675.     {
  676.         if (shape->IsPublished())
  677.         {
  678.             if (!temp.Contains(shape->GetPublishLink()))
  679.                 temp.AddLast(shape->GetPublishLink());
  680.         }
  681.     }
  682.     
  683.     //--- Update affected links ---
  684.     ODUpdateID updateID = fDrawPart->GetSession(ev)->UniqueUpdateID(ev);
  685.     CDrawPublishLinkCollectionIterator tempIte(&temp);
  686.     for (CDrawPublishLink* link = tempIte.First(); tempIte.IsNotComplete(); link = tempIte.Next())
  687.     {
  688.         link->ContentUpdated(ev, updateID);
  689.     }
  690.     
  691.     //--- Notify frames ---
  692.     GetPresentation(ev)->ContentUpdated(ev);
  693.     
  694.     temp.RemoveAll();
  695. }
  696.  
  697. //----------------------------------------------------------------------------------------
  698. //    CDrawSelection::IsSelectionLinkable
  699. //----------------------------------------------------------------------------------------
  700. //    Don't write a link spec if any of the selected shapes is in a link destination
  701.  
  702. FW_Boolean CDrawSelection::IsSelectionLinkable(Environment* ev)
  703. {
  704.     FW_Boolean result = TRUE;
  705.     
  706.     CDrawContentShapeIterator ite(fSelectionContent);
  707.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  708.     {
  709.         if (shape->IsInLinkDestination(ev))
  710.         {
  711.             result = FALSE;
  712.             break;
  713.         }
  714.         else if (shape->IsPublished())    // don't allow a shape to be published more than once
  715.         {
  716.             result = FALSE;
  717.             break;
  718.         }
  719.     }
  720.     
  721.     return result;
  722. }
  723.  
  724. //----------------------------------------------------------------------------------------
  725. //    CDrawSelection::CanPasteAsLink
  726. //----------------------------------------------------------------------------------------
  727. FW_Boolean CDrawSelection::CanPasteAsLink(Environment* ev, ODPasteAsMergeSetting& setting,
  728.                                           ODStorageUnit* su)
  729. {
  730.     // Check whether the storage unit contains mergeable content
  731.     if (su->Exists(ev, kODPropContents, fDrawPart->GetPartKind(ev), 0))
  732.         setting = kODPasteAsMerge;
  733.     else    // foreign content - cannot be merged
  734.         setting = kODPasteAsEmbedOnly;
  735.     
  736.     return fAllowLink;
  737. }
  738.  
  739. //----------------------------------------------------------------------------------------
  740. //    CDrawSelection::IsMouseInDraggableItem
  741. //----------------------------------------------------------------------------------------
  742.  
  743. FW_Boolean CDrawSelection::IsMouseInDraggableItem(Environment* ev, FW_CFrame* frame, 
  744.                                                 const FW_CMouseEvent& theMouseEvent, 
  745.                                                 FW_Boolean inBackground)
  746. {    
  747.     fClickedHandle = 0;
  748.     fAnchorShape = NULL;
  749.  
  750.     if (!inBackground && fDrawPart->GetTool() != kSelectTool)
  751.         return FALSE;
  752.         
  753.     FW_CViewContext vc(ev, frame->GetContentView(ev), theMouseEvent.GetFacet(ev));
  754.  
  755.     // ----- Look first for a handle -----
  756.     FW_CPoint where = theMouseEvent.GetMousePosition(ev, FW_CMouseEvent::kFrame);
  757.     frame->GetContentView(ev)->FrameToViewContent(ev, where);
  758.  
  759.     CBaseShape* clickedShape = WhichHandle(ev, vc, where, fClickedHandle);
  760.     if (clickedShape != NULL)
  761.     {
  762.         fAnchorShape = clickedShape;
  763.         return FALSE;            // if in a handle we won't drag
  764.     }
  765.     
  766.     // ----- then look for a selected shape -----
  767.     CBaseShape* shape = fDrawPart->WhichShape(ev, vc, theMouseEvent, TRUE);
  768.     
  769.     if (shape != NULL && shape->IsSelectedShape())
  770.     {
  771.         fAnchorShape = shape;
  772.         return TRUE;
  773.     }
  774.     
  775.     return FALSE;
  776. }
  777.  
  778. //----------------------------------------------------------------------------------------
  779. // CDrawSelection::UpdateSelectionOnMouseDown
  780. //----------------------------------------------------------------------------------------
  781.  
  782. void CDrawSelection::UpdateSelectionOnMouseDown(Environment* ev, 
  783.                                             const FW_CMouseEvent& mouseEvent,
  784.                                             ODFacet* embeddedFacet,
  785.                                             FW_Boolean inEmbeddedFrameBorder,
  786.                                             FW_Boolean inBackground)
  787. {
  788.     if (inEmbeddedFrameBorder)
  789.     {
  790.         fClickedHandle = 0;
  791.         fAnchorShape = NULL;
  792.  
  793.         CProxyShape *theShape = (CProxyShape*)fDrawPart->GetProxy(ev, embeddedFacet->GetFrame(ev));
  794.         FW_ASSERT(theShape);
  795.         
  796.         if (!theShape->IsSelectedShape())
  797.             AddToSelection(ev, theShape, TRUE);        
  798.         
  799.         fAnchorShape = theShape;
  800.     }
  801.     else if (fDrawPart->GetTool() == kSelectTool || inBackground)
  802.     {
  803.         FW_CFrame *frame = FW_CFrame::ODtoFWFrame(ev, mouseEvent.GetFacet(ev)->GetFrame(ev));
  804.         FW_CViewContext vc(ev, frame->GetContentView(ev), mouseEvent.GetFacet(ev));
  805.         
  806.         // ----- First look if we are in a resize handle -----
  807.         FW_CPoint where = mouseEvent.GetMousePosition(ev, FW_CMouseEvent::kFrame);
  808.         frame->GetContentView(ev)->FrameToViewContent(ev, where);
  809.     
  810.         short  clickedHandle;
  811.         if (WhichHandle(ev, vc, where, clickedHandle) != NULL)
  812.             return;
  813.  
  814.         // ----- So now we are not in a handle -----
  815.         CBaseShape* clickedShape = fDrawPart->WhichShape(ev, vc, mouseEvent, FALSE);
  816.         if (clickedShape)
  817.         {
  818.             if (mouseEvent.IsExtendModifier(ev))
  819.             {
  820.                 if (clickedShape->IsSelectedShape())
  821.                 {
  822.                     RemoveFromSelection(ev, clickedShape, !inBackground);
  823.                     if (clickedShape == fAnchorShape)
  824.                         fAnchorShape = NULL;
  825.                 }
  826.                 else
  827.                 {
  828.                     AddToSelection(ev, clickedShape, !inBackground);
  829.                     fAnchorShape = clickedShape;
  830.                 }
  831.             }
  832.             else if (!clickedShape->IsSelectedShape())
  833.             {
  834.                 fAnchorShape = clickedShape;
  835.                 CloseSelection(ev);
  836.                 AddToSelection(ev, clickedShape, !inBackground);
  837.             }    
  838.         }
  839.     }
  840. }
  841.  
  842. //----------------------------------------------------------------------------------------
  843. //    CDrawSelection::DeleteSelection
  844. //----------------------------------------------------------------------------------------
  845. void CDrawSelection::DeleteSelection(Environment* ev)
  846. {
  847.     CBaseShape *shape;
  848.     while ((shape = fSelectionContent->GetFirstShape()) != NULL)
  849.     {
  850.         DoRemove(ev, shape);                        // Remove from selection
  851.         fDrawPart->RemoveShapeFromPart(ev, shape);    // Remove from part
  852.         delete shape;
  853.     }
  854. }
  855.  
  856. //----------------------------------------------------------------------------------------
  857. //    CDrawSelection::IsOKtoEdit
  858. //----------------------------------------------------------------------------------------
  859.  
  860. FW_Boolean CDrawSelection::IsOKtoEdit(Environment* ev)
  861. {
  862.     // Check for a read-only part
  863.     if (fDrawPart->IsReadOnly(ev))
  864.         return FALSE;
  865.  
  866.     // check whether any of the selected shapes is in a link destination
  867.     if (this->IsShapeInLinkDestination(ev))
  868.         return FALSE;
  869.  
  870.     return TRUE;
  871. }
  872.  
  873. //----------------------------------------------------------------------------------------
  874. //    CDrawSelection::IsShapeInLinkDestination
  875. //----------------------------------------------------------------------------------------
  876.  
  877. FW_Boolean CDrawSelection::IsShapeInLinkDestination(Environment* ev)
  878. {
  879.     // check whether the presentation's frame is in a link destination
  880.     FW_CPresentationFrameIterator piter(ev, fPresentation);
  881.     CDrawFrame* drawFrame = (CDrawFrame*)piter.First(ev);
  882.     if (drawFrame->IsInLinkDestination(ev))
  883.         return TRUE;
  884.  
  885.     // check whether any of the selected shapes is in a link destination
  886.     CDrawContentShapeIterator iter(fSelectionContent);
  887.     for (CBaseShape *shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  888.     {
  889.         if (shape->IsInLinkDestination(ev))
  890.             return TRUE;            // can't edit a subscribed shape
  891.     }
  892.  
  893.     return FALSE;
  894. }
  895.  
  896. //----------------------------------------------------------------------------------------
  897. //    CDrawSelection::GetSelectionPenSize
  898. //----------------------------------------------------------------------------------------
  899.  
  900. FW_Boolean CDrawSelection::GetSelectionPenSize(Environment* ev, FW_Fixed& penSize)
  901. {
  902.     CDrawContentShapeIterator iter(fSelectionContent);
  903.     FW_Boolean first = TRUE;
  904.     for (CBaseShape *shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  905.     {
  906.         if (first)
  907.         {
  908.             penSize = shape->GetPenSize();
  909.             first = FALSE;
  910.         }
  911.         else
  912.         {
  913.             if (shape->GetPenSize() != penSize)
  914.                 return FALSE;
  915.         }
  916.     }
  917.     
  918.     return TRUE;
  919. }
  920.  
  921. //----------------------------------------------------------------------------------------
  922. //    CDrawSelection::SelectContent
  923. //----------------------------------------------------------------------------------------
  924. void CDrawSelection::SelectContent(Environment* ev, CDrawContent* content)
  925. {
  926.     this->CloseSelection(ev);
  927.  
  928.     CDrawContentShapeIterator it(content);
  929.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  930.     {
  931.         this->AddToSelection(ev, shape, TRUE);
  932.     }
  933. }
  934.  
  935. //----------------------------------------------------------------------------------------
  936. //    CDrawSelection::GetDrawContent
  937. //----------------------------------------------------------------------------------------
  938.  
  939. CDrawContent* CDrawSelection::GetDrawContent(Environment* ev)
  940. {
  941.     return fSelectionContent;
  942. }
  943.